//////////////////////////////////////////////////////////////////////////

#ifndef _LOADER_H_
#include "loader.h"
#endif

//////////////////////////////////////////////////////////////////////////

#ifndef _SERVERSTATE_H_
#include "serverstate.h"
#endif

//////////////////////////////////////////////////////////////////////////


Loader::Loader( const Buffer& _buffer )
: m_Buffer(_buffer)
{
}


//////////////////////////////////////////////////////////////////////////


ServerState Loader::LoadServerState()
{
    // Save players
    PlayersList playerslist;
    size_t playersCount = m_Buffer.ReadSize_t();
    for ( size_t i = 0; i < playersCount; i++ )
        playerslist.push_back( LoadPlayer() );

    // Save bullets
    BulletsList bulletsList;
    size_t bulletsCount = m_Buffer.ReadSize_t();
    for ( size_t i = 0; i < bulletsCount; i++ )
        bulletsList.push_back( LoadObject<Bullet>() );


    // Save walls
    WallsList wallsList;
    size_t wallsCount = m_Buffer.ReadSize_t();
    for ( size_t i = 0; i < wallsCount; i++ )
        wallsList.push_back( LoadObject<Wall>() );

    return ServerState(playerslist, bulletsList, wallsList);
}


//////////////////////////////////////////////////////////////////////////


ClientInput Loader::LoadClientInput()
{
    ClientInput clientInput;
    // Save actions
    clientInput.SetActions( m_Buffer.ReadUInt() );

    // Save mouse position
    Point position;
    position.x = m_Buffer.ReadFloat();
    position.y = m_Buffer.ReadFloat();

    clientInput.SetMousePosition(position);

    return clientInput;
}



//////////////////////////////////////////////////////////////////////////


template<typename ObjT>
ObjT Loader::LoadObject()
{
    int ID = m_Buffer.ReadInt();

    ObjT obj(ID);

    Point point;
    point.x = m_Buffer.ReadFloat();
    point.y = m_Buffer.ReadFloat();

    obj.SetPosition(point);

    return obj;
}


//////////////////////////////////////////////////////////////////////////


Player Loader::LoadPlayer()
{
    int ID = m_Buffer.ReadInt();

    Player obj(ID);

    Point point;
    point.x = m_Buffer.ReadFloat();
    point.y = m_Buffer.ReadFloat();

    obj.SetPosition(point);
    obj.SetHealthPoints( m_Buffer.ReadInt() );

    return obj;
}


//////////////////////////////////////////////////////////////////////////


ClientInputPacket Loader::LoadClientInputPacket()
{
    size_t creationTime = m_Buffer.ReadSize_t();
    ClientInput clientInput = LoadClientInput();

    return ClientInputPacket(creationTime, clientInput);
}


//////////////////////////////////////////////////////////////////////////


ClientInfo Loader::LoadClientInfo()
{
    size_t size = m_Buffer.ReadSize_t();
    char* nickName = new char[size];
    m_Buffer.ReadMemory(nickName, size);
    return ClientInfo(nickName);

}


//////////////////////////////////////////////////////////////////////////


ServerInfo Loader::LoadServerInfo()
{
    return ServerInfo();
}


//////////////////////////////////////////////////////////////////////////


ServerStatePacket Loader::LoadServerStatePacket()
{
    size_t creationTime = m_Buffer.ReadSize_t();
    ServerState serverState = LoadServerState();
    return ServerStatePacket(creationTime, serverState);        
}


//////////////////////////////////////////////////////////////////////////


ServerStatisticsPacket Loader::LoadServerStatisticsPacket()
{
    size_t creationTime = m_Buffer.ReadSize_t();
    PlayersInfo playersInfo;

    size_t infoSize = m_Buffer.ReadSize_t();

    for ( size_t i = 0; i < infoSize; i++ )
    {
        int playerID = m_Buffer.ReadInt();
        size_t nameSize = m_Buffer.ReadSize_t();
        char* name = new char[nameSize];
        m_Buffer.ReadMemory(name, sizeof(char)*nameSize);
        int kills = m_Buffer.ReadInt();
        int dies = m_Buffer.ReadInt();

        playersInfo.AddPlayer(playerID, name, kills, dies);
        delete[] name;
    }

    return ServerStatisticsPacket(creationTime, playersInfo);
}


//////////////////////////////////////////////////////////////////////////


ServerInfoPacket Loader::LoadServerInfoPacket()
{
    return ServerInfoPacket( LoadServerInfo() );
}


//////////////////////////////////////////////////////////////////////////


ServerEventPacket Loader::LoadServerEventPacket()
{
    int playerID = m_Buffer.ReadInt();
    int killerID = m_Buffer.ReadInt();
    return ServerEventPacket(playerID, killerID);
}


//////////////////////////////////////////////////////////////////////////


ServerStartPacket Loader::LoadServerStartPacket()
{
    size_t size = m_Buffer.ReadSize_t();
    char* mapName = new char[size];
    m_Buffer.ReadMemory(mapName, size);
    return ServerStartPacket(mapName);
}


//////////////////////////////////////////////////////////////////////////


ClientInfoPacket Loader::LoadClientInfoPacket()
{
    return ClientInfoPacket( LoadClientInfo() );
}


//////////////////////////////////////////////////////////////////////////


ClientIDPacket Loader::LoadClientIDPacket()
{
    return ClientIDPacket( m_Buffer.ReadInt() );
}


//////////////////////////////////////////////////////////////////////////
